class MyPromise {
    constructor(executor) {
        console.log("constructor", this)
        this.status = "pending"
        this.data = ""
        this.onResolveCallback = []
        this.onRejectedCallback = []
        try {
            // 回调函数this指向看执行的函数时的上下文环境
            // bind绑定this 函数内的this指向是调用时this而不是绑定的时候? 
            // executor这时调用
            executor(this.resolve.bind(this), this.reject.bind(this))
        } catch (e) {
            this.reject(e)
        }
    }
    resolve(value) {
        if (this.status === "pending") {
            this.status = 'resolved'
            this.data = value
            for (const func of this.onResolveCallback) {
                func(this.data)
            }
        }
    }
    reject(reason) {
        if (this.status === "pending") {
            this.status = 'rejected'
            this.data = reason
            for (const func of this.onRejectedCallback) {
                func(this.data)
            }
        }
    }
    resolvePromise(promise2, x, resolve, reject) {
        let called = false
        if (promise2 === x) {
            console.log("x第一种 --- ", x)
            return reject(new TypeError('Chaining cycle deteced for promise'))
        } else if (x instanceof MyPromise) {
            console.log("x第二种 --- ", x)
            if (x.status === "pending") {
                x.then(function (value) {
                    resolvePromise(promise2, value, resolve, reject)
                }, reject)
            } else {
                x.then(resolve, reject)
            }
            return
        } else if (x !== null && (x.toString() === '[object Object]' || x.toString() === "[object Function]")) {
            console.log("x第三种 --- ", x)
            try {
                const then = x.then
                if (typeof then === "function") {
                    then.call(x, y => {
                        console.log("function", this)
                        if (called) return
                        called = true
                        this.resolvePromise(promise2, y, resolve, reject)
                    }, r => {
                        if (called) return
                        called = true
                        reject(r)
                    })
                } else {
                    if (called) return
                    called = true
                    resolve(x)
                }
            } catch (e) {
                if (called) return
                called = true
                reject(e)
            }
        } else {
            console.log("x第四种 --- ", x)
            resolve(x)
        }
    }
    then(onResolved, onRejected) {
        // 此处的this是调用then的promise
        // 实现值穿透
        onResolved = typeof onResolved === 'function' ? onResolved : function (v) { return v }
        onRejected = typeof onRejected === "function" ? onRejected : function (e) { return e }

        let promise2
        promise2 = new MyPromise((resolve, reject) => {
            console.log("promise2", this) // promise1
            if (this.status === "resolved") {
                setTimeout(() => {
                    try {
                        const x = onResolved(this.data)
                        console.log("xxxx --- ", x)
                        this.resolvePromise(promise2, x, resolve, reject)
                    } catch (e) {
                        reject(e)
                    }
                }, 0)

            }
            if (this.status === "rejected") {
                setTimeout(() => {
                    try {
                        const x = onRejected(this.data)
                        this.resolvePromise(promise2, x, resolve, reject)
                    } catch (e) {
                        reject(e)
                    }
                }, 0)

            }
            if (this.status === "pending") {
                this.onResolveCallback.push(() => {
                    setTimeout(() => {
                        try {
                            const x = onResolved(this.data)
                            this.resolvePromise(promise2, x, resolve, reject)
                        } catch (e) {
                            reject(e)
                        }
                    }, 0)
                })
                this.onRejectCallback.push(() => {
                    setTimeout(() => {
                        try {
                            const x = onRejected(this.data)
                            this.resolvePromise(promise2, x, resolve, reject)
                        } catch (e) {
                            reject(e)
                        }
                    }, 0)
                })
            }
        })
        return promise2
    }

}
/* var p = new Promise((resolve, reject) => {
    resolve("hellow")
    console.log("this11 --- ", this)
}).then(v => {
    console.log("then__value", v)
    console.log("this22 --- ", this)
    return "hhh"
}).then(function (data) {
    console.log(data)
})
var p = new MyPromise((resolve, reject)=>{
    resolve("hellow")
}).then(v => {
    console.log("thisPPPP", this) // window
    console.log("then --- 1 ", v)
    return 112
}).then(res => {
    console.log("then --- 2 ", res)
}) */
let obj = {
    then(resolve, reject){
        resolve(11)
    }
}
let p1 = Promise.resolve(obj)
console.log(p1)
p1.then(function (data){
    console.log(data)
})
